using System;
using System.Collections.Generic;
using System.Linq;

namespace SmartSite.Frame
{
    public static class BytesExtention
    {
        public static List<byte> PackFrameForSynchronization(this IEnumerable<byte> bytes)
        {
            if(bytes == null)
                throw new ArgumentNullException(nameof(bytes));

            var result = bytes.ToList().DuplicateDle();
            result.Insert(0, (byte)DownlinkFrameFormatEnum.STX);
            result.Insert(0, (byte)DownlinkFrameFormatEnum.DLE);
            result.Add((byte)DownlinkFrameFormatEnum.DLE);
            result.Add((byte)DownlinkFrameFormatEnum.ETX);
            return result;
        }

        public static List<byte> UnpackFrameForSynchronization(this IEnumerable<byte> bytes)
        {
            if(bytes == null)
                throw new ArgumentNullException(nameof(bytes));

            List<byte> result = bytes.ToList();

            result.RemoveAt(0);
            result.RemoveAt(0);
            result.RemoveAt(result.Count - 1);
            result.RemoveAt(result.Count - 1);
            result.RemoveDuplicateDle();
            return result;
        }

        public static List<byte> DuplicateDle(this List<byte> bytes)
        {
            if(bytes == null)
                throw new ArgumentNullException(nameof(bytes));

            for (int i = bytes.FindLastIndex((x) => x == (byte)DownlinkFrameFormatEnum.DLE);
                i != -1;
                i = bytes.FindLastIndex(i - 1, (x) => x == (byte)DownlinkFrameFormatEnum.DLE))
            {
                bytes.Insert(i, (byte)DownlinkFrameFormatEnum.DLE);
                if (i <= 0) break;
            }

            return bytes;
        }

        public static List<byte> RemoveDuplicateDle(this List<byte> bytes)
        {
            if(bytes == null)
                throw new ArgumentNullException(nameof(bytes));

            for (int i = bytes.FindIndex((x) => x == (byte)DownlinkFrameFormatEnum.DLE) + 1;
                i != 0 && i < bytes.Count;
                i = bytes.FindIndex(i, (x) => x == (byte)DownlinkFrameFormatEnum.DLE) + 1)
            {
                if (bytes[i] == (byte)DownlinkFrameFormatEnum.DLE) bytes.RemoveAt(i);
            }

            return bytes;
        }

    }
}